package com.test.xq.customdemo.customtools;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

/**
 * Created by xq on 17/4/26.
 */


//Path之基本操作
public class CustomView4 extends View {

    private Paint mPaint = new Paint();
    private int mWidth,mHeight;

    public CustomView4(Context context) {
        super(context);
    }

    public CustomView4(Context context, AttributeSet attrs) {
        super(context, attrs);
        initPaint();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth=w;
        mHeight=h;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        otherMethed(canvas);
    }

    private void initPaint() {
        mPaint.setColor(Color.BLACK);           // 画笔颜色 - 黑色
        mPaint.setStyle(Paint.Style.STROKE);    // 填充模式 - 描边
        mPaint.setStrokeWidth(10);              // 边框宽度 - 10
    }

    private void drawCustomPathLine(Canvas canvas) {
        //第1组: moveTo、 setLastPoint、 lineTo 和 close

        //首先讲解的的LineTo，为啥先讲解这个呢？
        //是因为moveTo、 setLastPoint、 close都无法直接看到效果，借助有具现化效果的lineTo才能让这些方法现出原形。

        //再仔细一看，这个lineTo除了line外还有一个to呢，to翻译过来就是“至”，到某个地方的意思，lineTo难道是指从某个点到参数坐标点之间连一条线？
        //没错，你猜对了，但是这某个点又是哪里呢？
        //前面我们提到过Path可以用来描述一个图像的轮廓，图像的轮廓通常都是用一条线构成的，所以这里的某个点就是上次操作结束的点，如果没有进行过操作则默认点为坐标原点。
        canvas.translate(mWidth / 2, mHeight / 2);  // 移动坐标系到屏幕中心(宽高数据在onSizeChanged中获取)

        Path path = new Path();                     // 创建Path

//        path.lineTo(200, 200);                      // lineTo
//        path.lineTo(200,0);
//        path.lineTo(0,0);
//
//        canvas.drawPath(path, mPaint);              // 绘制Path

        //moveTo 和 setLastPoint：
        //方法名	              简介	                是否影响之前的操作	是否影响之后操作
        //moveTo	      移动下一次操作的起点位置	          否	            是
        //setLastPoint  设置之前操作的最后一个点位置	          是	            是
//        path.lineTo(200, 200);                      // lineTo
//        path.moveTo(200,100);                       // moveTo
//        path.lineTo(200,0);                         // lineTo
//        canvas.drawPath(path, mPaint);              // 绘制Path

//        path.lineTo(200, 200);                      // lineTo
//        path.setLastPoint(200,100);                 // setLastPoint
//        path.lineTo(200,0);                         // lineTo
//        canvas.drawPath(path, mPaint);              // 绘制Path

        //close方法用于连接当前最后一个点和最初的一个点(如果两个点不重合的话)，最终形成一个封闭的图形。
        path.lineTo(200, 200);                      // lineTo
        path.lineTo(200,0);                         // lineTo
        path.close();                               // close
        canvas.drawPath(path, mPaint);              // 绘制Path
    }

    private void drawCustomPathGraph(Canvas canvas) {
        //第2组: addXxx与arcTo
        //这次内容主要是在Path中添加基本图形，重点区分addArc与arcTo。

        //Path.Direction
//        Direction的意思是 方向，趋势。 点进去看一下会发现Direction是一个枚举(Enum)类型，里面只有两个枚举常量，如下：
//        类型  	解释    	            翻译
//        CW	  clockwise	            顺时针
//        CCW	counter-clockwise	    逆时针
        // 作用 在添加图形时确定闭合顺序(各个点的记录顺序)   对图形的渲染结果有影响(是判断图形渲染的重要条件)

        canvas.translate(mWidth / 2, mHeight / 2);  // 移动坐标系到屏幕中心(宽高数据在onSizeChanged中获取)
        Path path = new Path();                     // 创建Path
//        path.addRect(-200,-200,200,200, Path.Direction.CW);
//        canvas.drawPath(path,mPaint);

        //这个东东是自带隐身技能的，想要让它现出原形，就要用到咱们刚刚学到的setLastPoint(重置当前最后一个点的位置)。
        path.addRect(-200,-200,200,200, Path.Direction.CW);
        path.setLastPoint(-300,300);                // <-- 重置最后一个点的位置
        canvas.drawPath(path,mPaint);
        //交换坐标点的顺序可能就会影响到某些绘制内容哦，例如上面的例子，你可以尝试交换两个坐标点，或者指定另外两个点来作为参数，虽然指定的是同一个矩形，但实际绘制出来是不同的哦。

    }

    private void addPath(Canvas canvas){
        //第二类(Path)
        //这个相对比较简单，也很容易理解，就是将两个Path合并成为一个。
        canvas.translate(mWidth / 2, mHeight / 2);  // 移动坐标系到屏幕中心
        canvas.scale(1,-1);                         // <-- 注意 翻转y坐标轴
        Path path =new Path();
        Path src =new Path();

        path.addRect(-200,-200,200,200, Path.Direction.CW);
        src.addCircle(0,0,100, Path.Direction.CW);

        path.addPath(src,0,200);
        mPaint.setColor(Color.BLACK);           // 绘制合并后的路径
        canvas.drawPath(path,mPaint);
    }

    private void addArc(Canvas canvas){
        //第三类(addArc与arcTo)
        //名称	作用                        	区别
        //addArc	添加一个圆弧到path	       直接添加一个圆弧到path中
        //arcTo	添加一个圆弧到path	添加一个圆弧到path，如果圆弧的起点和上次最后一个坐标点不相同，就连接两个点

        //forceMoveTo是什么作用呢？
        //这个变量意思为“是否强制使用moveTo”，也就是说，是否使用moveTo将变量移动到圆弧的起点位移
        canvas.translate(mWidth / 2, mHeight / 2);  // 移动坐标系到屏幕中心
        canvas.scale(1,-1);                         // <-- 注意 翻转y坐标轴

        Path path = new Path();
        path.lineTo(100,100);

        RectF oval = new RectF(0,0,300,300);
        //示例(addArc)：
        //path.addArc(oval,0,270);

        //示例(arcTo)：
        path.arcTo(oval,0,270);
        canvas.drawPath(path,mPaint);
    }

    private void otherMethed(Canvas canvas){
        //第3组：isEmpty、 isRect、isConvex、 set 和 offset

        //isEmpty  判断path中是否包含内容。
//        Path path = new Path();
//        Log.v("xq_msg",path.isEmpty()+"");
//
//        path.lineTo(100,100);
//        Log.v("xq_msg",path.isEmpty()+"");

        //isRect 判断path是否是一个矩形，如果是一个矩形的话，会将矩形的信息存放进参数rect中。
//        Path path = new Path();
//        path.lineTo(0,400);
//        path.lineTo(400,400);
//        path.lineTo(400,0);
//        path.lineTo(0,0);
//
//        RectF rect = new RectF();
//        boolean b = path.isRect(rect);
//        Log.v("xq_msg","isRect:"+b+"| left:"+rect.left+"| top:"+rect.top+"| right:"+rect.right+"| bottom:"+rect.bottom);

        //set 将新的path赋值到现有path。
//        canvas.translate(mWidth / 2, mHeight / 2);  // 移动坐标系到屏幕中心
//        canvas.scale(1,-1);                         // <-- 注意 翻转y坐标轴
//        Path path = new Path();                     // path添加一个矩形
//        path.addRect(-200,-200,200,200, Path.Direction.CW);
//        Path src = new Path();                      // src添加一个圆
//        src.addCircle(0,0,100, Path.Direction.CW);
//        path.set(src);                              // 大致相当于 path = src;
//        canvas.drawPath(path,mPaint);

        //offset 这个的作用也很简单，就是对path进行一段平移，它和Canvas中的translate作用很像，但Canvas作用于整个画布，而path的offset只作用于当前path。
        //public void offset (float dx, float dy)
        //public void offset (float dx, float dy, Path dst)
        //其实第二个方法中最后的参数dst是存储平移后的path的。
        canvas.translate(mWidth / 2, mHeight / 2);  // 移动坐标系到屏幕中心
        canvas.scale(1,-1);                         // <-- 注意 翻转y坐标轴
        Path path = new Path();
        path.addCircle(0,0,100, Path.Direction.CW); // path中添加一个圆形(圆心在坐标原点)
        Path dst = new Path();
        dst.addRect(-200,-200,200,200, Path.Direction.CW);  // dst中添加一个矩形
        path.offset(300,0,dst);                     // 平移
        canvas.drawPath(path,mPaint);               // 绘制path
        mPaint.setColor(Color.BLUE);                // 更改画笔颜色
        canvas.drawPath(dst,mPaint);                // 绘制dst
    }



}
